package com.ia2011.project1.demo;

import java.util.Iterator;
import java.util.List;
import java.util.Properties;

import aima.search.framework.Problem;
import aima.search.framework.Search;
import aima.search.framework.SearchAgent;
import aima.search.informed.HillClimbingSearch;
import aima.search.informed.SimulatedAnnealingSearch;

import com.ia2011.project1.aima.CSGoalTest;
import com.ia2011.project1.aima.CSHeuristicFunction;
import com.ia2011.project1.aima.CSSuccessorFunction;
import com.ia2011.project1.aima.CSSuccessorFunctionSA;
import com.ia2011.project1.debug.Debug;
import com.ia2011.project1.service.CarpoolingService;
import com.ia2011.project1.strategy.TStrategy;

public class CSDemo extends Debug {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		CarpoolingService cs = new CarpoolingService(200, 100, TStrategy.GOOD_ASSIGMENT);
		long timeStart = System.currentTimeMillis();
		CSHillClimbingSearch(cs);
//		CSSimulatedAnnealingSearch(cs, 1000, 30, 4, 0.002);
		long timeEnd = System.currentTimeMillis();
		info("duration:"+(timeEnd-timeStart));
	}

	/**
	 * 
	 * @param cs
	 * @param steps number of branches
	 * @param stiter - number of iteration
	 * @param k	- as increases - function starts decreasing later
	 * @param lamb - as increases - function decreases faster
	 */
	public static void CSSimulatedAnnealingSearch(CarpoolingService cs, int steps, int stiter, int k, double lamb) {
		info("Simulated Annealing...");
		try {
			Problem problem = new Problem(cs, new CSSuccessorFunctionSA(), new CSGoalTest(), new CSHeuristicFunction(1));
			SimulatedAnnealingSearch search = new SimulatedAnnealingSearch(steps, stiter, k, lamb);
			SearchAgent agent = new SearchAgent(problem, search);
			printActions(agent.getActions());
			printInstrumentation(agent.getInstrumentation());
		} catch (Exception e) {
			error("We've got an error: "+e.getMessage());
			e.printStackTrace();
		}
	}

	/**
	 * 
	 * @param cs
	 */
	private static void CSHillClimbingSearch(CarpoolingService cs) {
		info("Hill-Climbing Search...");
		try {
			Problem problem = new Problem(cs, new CSSuccessorFunction(), new CSGoalTest(), new CSHeuristicFunction(1));
			Search search = new HillClimbingSearch();
			SearchAgent searchAgent = new SearchAgent(problem, search);
			line();
			printActions(searchAgent.getActions());
			printInstrumentation(searchAgent.getInstrumentation());
		} catch (Exception e) {
			error("We've got an error: "+e.getMessage());
		}
		
		
	}
	
    private static void printActions(List actions) {
        for (int i = 0; i < actions.size(); i++) {
            String action = (String) actions.get(i);
            info(action);
        }
    }
    
    private static void printInstrumentation(Properties properties) {
        Iterator keys = properties.keySet().iterator();
        while (keys.hasNext()) {
            String key = (String) keys.next();
            String property = properties.getProperty(key);
            info(key + " : " + property);
        }
    }

}
